/*
* @Author: Ziwei Yang
* @Date:   2016-10-12
* @Last Modified by:   Manel
* @Last Modified time: 2017-03-16 15:45:04
*/

'use strict';

//Load modules
var mongojs = require('mongojs');
var profiler = require('v8-profiler');
var express = require('express');
var fs = require('fs');
var app = express();
var serv = require('http').Server(app);
var io = require('socket.io')(serv,{});

app.get('/',function(req,res){
	res.sendFile(__dirname + '/client/index.html');
});
app.get('/mapcreator',function(req,res){
	res.sendFile(__dirname + '/client/map_creator.html');
});
app.use('/client',express.static(__dirname + '/client'));
console.log("Server listening on port 2001");
serv.listen(2001);



//Constants
var SOCKET_LIST = {};
var MAP_WIDTH = 470;
var MAP_HEIGHT = 470;

var map = require('./maps/cross-map.json');

var initPack = {
	player:[],
	bullet:[],
};
var removePack = {
	player:[],
	bullet:[],
}
//Connections
io.sockets.on('connection',function(socket){
	console.log('Server connected');
	SOCKET_LIST[socket.id] = socket;
	socket.on('newPlayer',function(data){
		connectionLog(data.username,socket.handshake.address);

		Player.onConnect(socket);

	});
	socket.on('disconnect',function(){
		delete SOCKET_LIST[socket.id];
		Player.onDisconnect(socket);
	});
});


//Games
var connectionLog = function(username,ip){
	console.log("New player connected");
	console.log("Username: " + username);
	console.log("IP: " + ip);
}

var Entity = function(param){
	var self = {};
	self.id = '';
	self.x = Math.floor(Math.random() * 470);
	self.y = Math.floor(Math.random() * 470);
	self.direction = "up";
	self.team = undefined;
	if(param){
		if(param.id) self.id = param.id;
		if(param.x) self.x = param.x;
		if(param.y) self.y = param.y;
		if(param.direction) self.direction = param.direction;
		if(param.team) self.team = param.team;
	}
	return self;
}

var Player = function(param){
	var self = new Entity(param);
	self.team = 'player';
	self.speed = 10;
	self.pressingRight;
	self.pressingLeft;
	self.pressingUp;
	self.pressingDown;
	self.direction = 'up';
	self.update = function(){
		self.updatePosition();
		if(self.pressingAttack){
			self.shootBullet();
		}
	}
	self.updatePosition = function(){
		if(self.pressingRight){
			self.direction = 'right';
			if(self.x + self.speed > MAP_WIDTH+10){
				//self.x = MAP_WIDTH;
			}else{
				self.x += self.speed;
			}
		}else if(self.pressingLeft){
			self.direction = 'left';
			if(self.x - self.speed < -10){
				//self.x = 0;
			}else{
				self.x -= self.speed;
			}
		}else{
			self.x = self.x;
		}
		if(self.pressingUp){
			self.direction = 'up';
			if(self.y - self.speed < -10){
				//self.y = 0;
			}else{
				self.y -= self.speed;
			}
		}else if(self.pressingDown){
			self.direction = 'down';
			if(self.y + self.speed > MAP_HEIGHT+15){
				//self.y = MAP_HEIGHT;
			}else{
				self.y += self.speed;
			}
		}else{
			self.y = self.y;
		}
	}
	self.shootBullet = function(){
		new Bullet({
			parent: self.id,
			x: self.x,
			y: self.y,
			direction: self.direction,
			team: self.team,
		});
	}
	self.getUpdatePack = function(){
		return {
			id: self.id,
			x: self.x,
			y: self.y,
			direction: self.direction,
		}
	}

	Player.list[self.id] = self;
	initPack.player.push(self);
	return self;
}
Player.list = {};
Player.onConnect = function(socket){
	var player = Player({id:socket.id});
	var pack = {
		id: socket.id,
		map: map,
		player: Player.getAllInitPack(),
		bullet: Bullet.getAllInitPack(),
	}
	socket.emit('initialization',pack);
	socket.on('keyPress',function(data){
		if(data.inputId === 'left'){
			player.pressingLeft = data.state;
		}else if(data.inputId === 'right'){
			player.pressingRight = data.state;
		}else if(data.inputId === 'up'){
			player.pressingUp = data.state;
		}else if(data.inputId === 'down'){
			player.pressingDown = data.state;
		}else if(data.inputId === 'attack'){
			//player.pressingAttack = data.state;
			player.shootBullet();
		}else if(data.inputId === 'mouseAngle'){
			player.mouseAngle = data.state;
		}
	});
}
Player.update = function(){
	var pack = [];
	for(var i in Player.list){
		var player = Player.list[i];
		player.update();
		pack.push(player.getUpdatePack());
	}
	return pack;
}
Player.getAllInitPack = function(){
	var pack = [];
	for(var i in Player.list){
		var player = Player.list[i];
		pack.push(player);
	}
	return pack;
}
Player.onDisconnect = function(socket){
	delete Player.list[socket.id];
	removePack.player.push(socket.id);
}


var Bullet = function(param){
	var self = Entity(param);
	self.id = Math.random();
	self.parent = param.parent;
	self.speed = 20;
	self.toRemove = false;
	self.getUpdatePack = function(){
		return {
			id: self.id,
			x: self.x,
			y: self.y,
		}
	}
	self.update =  function(){
		self.updatePosition();
	}
	self.updatePosition = function(){
		switch(self.direction){
			case 'up':
				self.y -= self.speed;
			break;
			case 'down':
				self.y += self.speed;
			break;
			case 'left':
				self.x -= self.speed;
			break;
			case 'right':
				self.x += self.speed;
			break;
		}
	}
	self.getInitPack = function(){
		return {
			id: self.id,
			x:self.x,
			y:self.y,
			direction: self.direction,
		}
	}
	self.checkCollison = function(){
		//Collision out of map
		if(self.x > MAP_WIDTH+10 || self.x < -10) self.toRemove = true;
		if(self.y > MAP_HEIGHT+10 || self.y < -10) self.toRemove = true;
		//Collision with another player
		for(var i in Player.list){
			var player = Player.list[i];
			if(self.parent === player.id) continue;
			if (self.x < player.x + 30 && self.x + 14 > player.x && self.y < player.y + 30 && 14 + self.y > player.y){
				self.toRemove = true;
			}
		}
		//Collision with another bullet
		for(var i in Bullet.list){
			var bullet = Bullet.list[i];
			if(self.parent === player.id) continue;
			if (self.x < bullet.x + 5 && self.x + 5 > bullet.x && self.y < bullet.y + 5 && 5 + self.y > bullet.y){
				self.toRemove = true;
				bullet.toRemove = true;
			}
		}
	}
	Bullet.list[self.id] = self;
	initPack.bullet.push(self.getInitPack());
}
Bullet.getAllInitPack = function(){
	var bullets = [];
	for(var i in Bullet.list){
		bullets.push(Bullet.list[i].getInitPack());
	}
	return bullets;
}
Bullet.update = function(){
	var pack = [];
	for(var i in Bullet.list){
		var bullet = Bullet.list[i];
		bullet.update();
		bullet.checkCollison();
		if(bullet.toRemove){
			removePack.bullet.push(bullet.id);
			delete Bullet.list[bullet.id];
		}else{
			pack.push(bullet.getUpdatePack());
		}
	}
	return pack;
}
Bullet.list = {};




setInterval(function(){
	var pack = {
		player: Player.update(), 
		bullet: Bullet.update(),
	};
	for(var i in SOCKET_LIST){
		var socket = SOCKET_LIST[i];
		socket.emit('update',pack);
		socket.emit('initialization',initPack);
		socket.emit('remove',removePack)
	}
	initPack.player = [];
	initPack.bullet = [];
	removePack.player = [];
	removePack.bullet = [];
},1000/30);